package node;

import lexer.LexType;
import parser.Parser;

import java.io.IOException;
import java.util.List;

public class MulExpNode extends ASTNode {
    public final String name = "<MulExp>";
    // MulExp → UnaryExp | MulExp ('\*' | '/' | '%') UnaryExp
    // 改写文法
    // MulExp → UnaryExp {('\*' | '/' | '%') UnaryExp}
    private final List<UnaryExpNode> unaryExpNodeList;
    private final List<String> mulOpList;

    public MulExpNode(List<UnaryExpNode> unaryExpNodeList, List<String> mulOpList) {
        this.unaryExpNodeList = unaryExpNodeList;
        this.mulOpList = mulOpList;
    }

    public List<String> getMulOpList() {
        return mulOpList;
    }

    @Override
    public void show() throws IOException {
        for (int i = 0; i < unaryExpNodeList.size(); i++) {
            if (i < mulOpList.size() + 1 && i != 0) {
                if (mulOpList.get(i - 1).equals("*")) {
                    Parser.parserWriter.write(LexType.MULT + " " + "*" + "\n");
                } else if (mulOpList.get(i - 1).equals("/")) {
                    Parser.parserWriter.write(LexType.DIV + " " + "/" + "\n");
                } else {
                    Parser.parserWriter.write(LexType.MOD + " " + "%" + "\n");
                }
            }

            unaryExpNodeList.get(i).show();
            Parser.parserWriter.write(name + "\n");
        }
    }

    public List<UnaryExpNode> getUnaryExpNodeList() {
        return unaryExpNodeList;
    }

    public int calculate() {
        // 确定当前MulExp是乘除法计算，即一定可以被计算出具体的数值
        // 输入：List<UnaryExpNode> unaryExpNodeList, List<String> mulOpList
        // 输出：一个int类型的数字
        int result = unaryExpNodeList.get(0).calculate();
        for (int i = 1; i < unaryExpNodeList.size(); i++) {
            if (mulOpList.get(i - 1).equals("*")) {
                result *= unaryExpNodeList.get(i).calculate();
            } else if (mulOpList.get(i - 1).equals("/")) {
                result /= unaryExpNodeList.get(i).calculate();
            } else {
                result %= unaryExpNodeList.get(i).calculate();
            }
        }
        return result;
    }

    public boolean canCaclulate() {
        for (UnaryExpNode unaryExpNode : unaryExpNodeList) {
            if (!unaryExpNode.canCaclulate()) {
                return false;
            }
        }
        return true;
    }

}
